#pragma once
namespace snow {
	template <typename T>
	class Cube
	{
	public:
		Cube(int _channel,int _width,int _height,int _padding)
		:m_nWidth(_width),
		m_nHeight(_height),
		m_nChannel(_channel),
		m_nPadding(_padding)
		{
			int size = (m_nWidth + m_nPadding) * (m_nHeight + m_nPadding) * m_nChannel;
			ptrData = new T[size];
			memset(ptrData, 0, sizeof(T) * size);
		}

		~Cube() {
			delete[] ptrData;
		}
	private:
		int m_nWidth;
		int m_nHeight;
		int m_nChannel;
		int m_nPadding;

		T* ptrData;	
		
	public:		
		int getWidth() { return m_nWidth; }
		int getHeight() { return m_nHeight; }
		T& get(int channel, int row, int col) {
			int channel_size = (m_nWidth + 2 * m_nPadding) * (m_nHeight + 2 * m_nPadding);
			int line_size = (m_nWidth + 2 * m_nPadding);
			return *(ptrData + channel * channel_size + row * line_size + col);
		}

		void set(int channel, int row, int col, T value) {
			int channel_size = (m_nWidth + 2 * m_nPadding) * (m_nHeight + 2 * m_nPadding);
			int line_size = (m_nWidth + 2 * m_nPadding);
			*(ptrData + channel * channel_size + row * line_size + col) = value;
		}

		void fill(T* ptr, T padding_value) {
			int index = 0;
			for (int channel = 0; channel < m_nChannel; channel++, index++) {
				for (int row = 0; row < m_nHeight; row++) {
					for (int column = 0; column < m_nWidth; column++) {
						this->set(channel, row, column, *(ptr + index));
					}
				}
			}
		}

		void getSquare(T* pSquare,int filter_size,int channel,int center_row, int center_col) {
			int index = 0;
			int row = center_row + filter_size / 2;
			int col = center_col + filter_size / 2;
			int half_filter_size = filter_size / 2;

			for (int r = -half_filter_size; r <= -half_filter_size; r++) {
				for (int c = -half_filter_size; c <= -half_filter_size; c++) {
					*(pSquare + index) = this->get(channel, row + r, col + c);
					index++;
				}
			}
		}

		void print() {

		}
	};
}


